//
//  max.cpp
//  HelloWorld
//
//  Created by Kevin Tang on 11/12/14.
//  Copyright (c) 2014年 Kevin Tang. All rights reserved.
//

#include <iostream>
#include "Common.h"
#include "max.h"


void TemplateTest()
{
    int i=47;
    std::cout<<"max(7, i)"<< TEMP::max(7, i ) <<std::endl;//调用的是两个int,编译器产生如下函数
    //inline int const& max(int const& a ,int const& b )
    
    double f1 = 25.4f;
    double f2 = 32.8;
    std::cout<<"max(f1, f2)"<< TEMP::max(f1, f2 ) <<std::endl;//调用的是两个double,编译器产生如下函数
    //inline double const& max(double const& a ,double const& b )
    
    std::string str1 = "math";
    std::string str2 = "mathmatic";
    std::cout<<"max(str1, str1)"<< TEMP::max(str1, str2 ) <<std::endl;//调用的是两个std::string,编译器产生如下函数
    //inline std::string const& max(std::string const& a ,std::string const& b )
    //之所以能用 < 进行字串的比较，且得到正确的值,是因为std::string对此操作符进行了重载。
    
    //如果模板参数的类型，在不支持 max中的 > 比较操作，那么会报错。原因很简单，假如我们写了一个类，但是没有对其进行  < 这个操作符重载，
    //而我们对其使用了 <比较，肯定会出错。
    
    //TEMP::max(i, f1); //这里会出错，因为 max 的两个调用参数都是 T,而我们传入的一个是int ,另一个是  float ，所以会出错.
    //出错的原因是，模板不允许自动类型转换,即参数必须一致.即自变量参数必须一致
    
    //?那么我们要比较一个int,和一float型，模板方法该怎么写呢？
    int j = 20;
    double f3 = 55.32;
    std::cout << "TEMPA::MAX(int ,float)"<<TEMPA::max(j, f3)<<std::endl;
    //上面这种方法，产生了一些问题，看max.h头文件说明,为了区别，我们用了另一个命名空间
    
    //但我们可以在调用时指定模板参数(是指尖插号中的参数),注意我们用了另一个命名空间的max
    //这里的尖括号的参数，确定了模板函数中的T为double类型，而不是后面的调用参数(圆括号中的类型)来推导出模板参数<尖括号的类型>
    std::cout << "TEMP::MAX<double>(int ,float)"<<TEMP::max<double>(j, f3)<<std::endl;
    
    //下面使用权TEMPC 中的方案，然而，我们必须写上所有的模板参数，因为TEMPC::max<double>(j, f3),编译器无法推导出返回类型RT
    //原因是RT，并不是调用参数，因为自变量推导，即以调用参数推导出，但由于RT,并不是调用参数，编译器无法推导
    //为了解决写代码时，过于冗长的问题，我们可以把RT的位置放到最前面，即TEMPD的模式.
    std::cout << "TEMC::MAX<double>(int ,float)"<<TEMPC::max<double,int,double>(j, f3)<<std::endl;
    
    //模式D,
    std::cout << "TEMPD::MAX<double>(int ,float)"<<TEMPD::max<double>(j, f3)<<std::endl;
    
    
    //＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝接下来，要学习模板函数重载＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
    
    std::cout << "TEMPE::MAX(T const& a,T const& b,T const& c)经由自变量推导"<<TEMPE::max(7, 42,68)<<std::endl;
    std::cout << "TEMPE::MAX(T const& a,T const& b)经由自变量推导"<<TEMPE::max(7.0, 4.0)<<std::endl;
    std::cout << "TEMPE::MAX(T const& a,T const& b)经由自变量推导"<<TEMPE::max('z', 'b')<<std::endl;
    std::cout << "TEMPE::MAX(int const& a,int const& b)非模板函数，可以与模板函数共存，"
    <<"且编译器优先非模板函数 : "<<TEMPE::max(1, 2)<<std::endl;
    std::cout << "TEMPE::MAX(T const& a,T const& b) 经由自变量推导,调用模板，因为尖括表示我们要用模板,"
    <<"但时尖括号<>中的模板参数未知，只能通过调用参数推导。 : "<<TEMPE::max< >(1, 2)<<std::endl;
    std::cout << "TEMPE::MAX<double>(T const& a,T const& b) 无需推导，我们已告知编译器,模板参数是double: "
    <<TEMPE::max< double>(1, 2)<<std::endl;
    std::cout << "TEMPE::MAX(int const& a,int const& b) 无需推导，我们已告知编译器,模板参数是double: "
    <<TEMPE::max('a', 42.7)<<std::endl;
    
    
    
    
}